<?php
class Tedi_Date_Finder
{
    private $date;
    private $time;

    private $hour;
    private $minute;
    private $second;
    private $month;
    private $day;
    private $year;


    /**
     *
     * @param String $date Date in format Y-m-d
     */
    public function  __construct($date)
    {
        $this->date = $date;
        $this->time = strtotime($date);

        $this->hour   = date('H', $this->time);
        $this->minute = date('i', $this->time);
        $this->second = date('s', $this->time);
        $this->month  = date('m', $this->time);
        $this->day    = date('d', $this->time);
        $this->year   = date('Y', $this->time);
    }

    /**
     * Increase day
     *
     * @return Tedi_Date_Finder
     */
    public function getNextDay()
    {
        $this->day += 1;
        return $this;
    }

    /**
     * Increase month
     * @return Tedi_Date_Finder
     */
    public function getNextMonth()
    {
        $this->month += 1;
        return $this;
    }

    /**
     * Increase year
     *
     * @return Tedi_Date_Finder
     */
    public function getNextYear()
    {
        $this->year += 1;
        return $this;
    }

    /**
     * Search next Monday
     *
     * @return Tedi_Date_Finder
     */
    public function getNextMonday()
    {
        $this->_get_next_dayname('Mon');
        return $this;
    }

    /**
     * Search next Tuesday
     *
     * @return Tedi_Date_Finder
     */
    public function getNextTuesday()
    {
        $this->_get_next_dayname('Tue');
        return $this;
    }

    /**
     * Search next Wednesday
     *
     * @return Tedi_Date_Finder
     */
    public function getNextWednesday()
    {
        $this->_get_next_dayname('Wed');
        return $this;
    }

    /**
     * Search next Thursday
     *
     * @return Tedi_Date_Finder
     */
    public function getNextThursday()
    {
        $this->_get_next_dayname('Thu');
        return $this;
    }

    /**
     * Search next Friday
     * 
     * @return Tedi_Date_Finder
     */
    public function getNextFriday()
    {
        $this->_get_next_dayname('Fri');
        return $this;
    }

    /**
     * Search next Saturday
     *
     * @return Tedi_Date_Finder
     */
    public function getNextSaturday()
    {
        $this->_get_next_dayname('Sat');
        return $this;
    }

    /**
     * Search next Sunday
     * 
     * @return Tedi_Date_Finder
     */
    public function getNextSunday()
    {
        $this->_get_next_dayname('Sun');
        return $this;
    }


    public function incYear($i = 1)
    {
        $this->year += $i;
        return $this;
    }

    public function incMonth($i = 1)
    {
        $this->month += $i;
        return $this;
    }

    public function incWeek($i = 1)
    {
        $this->day += ($i * 7);
        return $this;
    }

    public function incDay($i = 1)
    {
        $this->day += $i;
        return $this;
    }

    public function incHour($i = 1)
    {
        $this->hour += $i;
        return $this;
    }

    public function incMinute($i = 1)
    {
        $this->minute += $i;
        return $this;
    }

    public function incSecond($i = 1)
    {
        $this->second += $i;
        return $this;
    }

    public function getNearest($days = array('Mon'))
    {
        $i = 1;
        $time = mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + $i, $this->year);

        while(!in_array(date('D', $time), $days))
        {
            ++$i;
            $time = mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + $i, $this->year);
        }

        $this->year   = date('Y', $time);
        $this->month  = date('m', $time);
        $this->day    = date('d', $time);
        $this->hour   = date('H', $time);
        $this->minute = date('i', $time);
        $this->second = date('s', $time);

        return $this;
    }

    public function getFirstDayOfWeek()
    {
        if(date('w', $this->toString()) != 0)
        {
            $i = 1;
            $time = mktime($this->hour, $this->minute, $this->second, $this->month, $this->day - $i, $this->year);

            while(date('w', $time) != 0)
            {
                ++$i;
                $time = mktime($this->hour, $this->minute, $this->second, $this->month, $this->day - $i, $this->year);
            }

            $this->year   = date('Y', $time);
            $this->month  = date('m', $time);
            $this->day    = date('d', $time);
            $this->hour   = date('H', $time);
            $this->minute = date('i', $time);
            $this->second = date('s', $time);
        }

        return $this;
    }

    protected function _get_next_dayname($name)
    {
        $i = 1;
        $time = mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + $i, $this->year);

        while(date('D', $time) != $name)
        {
            ++$i;
            $time = mktime($this->hour, $this->minute, $this->second, $this->month, $this->day + $i, $this->year);
        }

        $this->year   = date('Y', $time);
        $this->month  = date('m', $time);
        $this->day    = date('d', $time);
        $this->hour   = date('H', $time);
        $this->minute = date('i', $time);
        $this->second = date('s', $time);
        
    }

    public function  __toString()
    {
        return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
    }

    public function toString($format = null)
    {
        if($format)
        {
            return date($format, $this->__toString());
        }
        return $this->__toString();
    }

    public function format($format)
    {
        return date($format, $this->__toString());
    }
}